#ifndef __CORE_HANDLEMANAGER__
#define __CORE_HANDLEMANAGER__

#include <vector>
#include <cassert>
#include "Handle.h"


namespace Core
{
	template<typename DATA>
	class HandleManager
	{
	private:
		typedef std::vector<DATA>         UserVec;
		typedef std::vector<unsigned int> MagicVec;
		typedef std::vector<unsigned int> FreeVec;

		

		UserVec  m_UserData;
		MagicVec m_MagicNumbers;
		FreeVec  m_FreeSlots;

	public:

		typedef CHandle<DATA>             HandleType;

		HandleManager()
		{
			
		}

		~HandleManager()
		{

		}

		DATA* accquire(HandleType& handle);
		void  release(HandleType handle);

		DATA* dereference(HandleType handle);

		const DATA* dereference(HandleType handle) const;


		unsigned int getUsedHandleCount() const
		{
			return (m_MagicNumbers.size() - m_FreeSlots.size());
		}

		bool HasUsedHandles()
		{
			return (getUsedHandleCount() != 0);
		}
	};

	template<typename DATA>
	DATA* HandleManager<DATA>::accquire(HandleType& handle)
	{
		unsigned int index;
		if (m_FreeSlots.empty())
		{
			index = m_MagicNumbers.size();
			handle.init(index);
			m_UserData.push_back(DATA());
			m_MagicNumbers.push_back(handle.getMagic());
		}

		else
		{
			index = m_FreeSlots.back();
			handle.init(index);
			m_FreeSlots.pop_back();
			m_MagicNumbers[index] = handle.getMagic();
		}

		return (m_UserData.begin() + index);
	}
}

#endif